package kr.pe.johnkim.pushchat.mobile.controller;

import kr.pe.johnkim.pushchat.mobile.domain.PushChatMember;
import kr.pe.johnkim.pushchat.mobile.service.PushChatMemberService;
import kr.pe.johnkim.pushchat.mobile.util.PushChatCommon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author : John_Kim <cale9797@gmail.com>
 * @date : 13. 6. 12.
 */
@Controller
@RequestMapping(value = "/pushChatMemberController")
public class PushChatMemberController {

    // SLF4J Logging
    private Logger logger = LoggerFactory.getLogger(PushChatMemberController.class);

    @Autowired
    private PushChatMemberService pushChatMemberService;

    @Autowired
    private PushChatCommon pushChatCommon;

    @Autowired
    private HttpServletRequest httpServletRequest;

    // 프로필 이미지 업로드 Directory.
    private @Value("${pushchat.upload.profile.image.directory}") String uploadProfileImageDirectory;

    // 프로필 이미지 업로드 URL.
    private @Value("${pushchat.upload.profile.image.url}") String uploadProfileImageUrl;

    // 프로필 썸네일 업로드 Directory.
    private @Value("${pushchat.upload.profile.thumbnail.directory}") String uploadProfileThumbnailDirectory;

    // 프로필 썸네일 업로드 URL.
    private @Value("${pushchat.upload.profile.thumbnail.url}") String uploadProfileThumbnailUrl;

    /**
     * 멤버 중복을 확인 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/selectDuplicationMember", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember selectDuplicationMember(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("selectDuplicationMember");
        return this.pushChatMemberService.selectDuplicationMember(pushChatMember);
    }

    /**
     * 멤버를 등록 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/registerMember", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember registerMember(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("registerMember");

        // 비밀번호를 암호화 해서 저장 한다.
        pushChatMember.setPassword(this.pushChatCommon.getEncodedPassword(pushChatMember.getPassword()));

        PushChatMember result = new PushChatMember();

        try {
            this.pushChatMemberService.registerMember(pushChatMember);
            result.setResult("SUCCESS");
            logger.info("success to register member.");
        } catch (Exception e) {
            result.setResult("FAIL");
            logger.info("fail to register member.");
        }

        return result;
    }

    /**
     * 멤버 로그인을 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember login(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("login");

        logger.info("memberId   : {}", pushChatMember.getMemberId());
        logger.info("password   : {}", pushChatMember.getPassword());
        logger.info("activateYn : {}", pushChatMember.getActivateYn());

        // 비밀번호를 암호화 해서 비교 한다.
        pushChatMember.setPassword(this.pushChatCommon.getEncodedPassword(pushChatMember.getPassword()));
        logger.info("password   : {}", pushChatMember.getPassword());

        return this.pushChatMemberService.login(pushChatMember);
    }

    /**
     * 멤버 목록을 가져 온다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/selectMemberList", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public List<PushChatMember> selectMemberList(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("selectMemberList");
        return this.pushChatMemberService.selectMemberList(pushChatMember);
    }

    /**
     * 사용자의 GCM / APNS Device Token 을 업데이트 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/updateRegistrationId", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember updateRegistrationId(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("updateRegistrationId");

        PushChatMember result = new PushChatMember();

        try {
            this.pushChatMemberService.updateRegistrationId(pushChatMember);
            result.setResult("SUCCESS");
            logger.info("success to update registrationId.");
        } catch (Exception e) {
            result.setResult("FAIL");
            logger.error("fail to update registrationId.");
        }

        return result;
    }

    /**
     * 멤버 정보를 가져 온다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/selectMemberInformation", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember selectMemberInformation(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("selectMemberInformation");

        return this.pushChatMemberService.selectMemberInformation(pushChatMember);
    }

    /**
     * 멤버를 검색 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/selectSearchMemberList", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public List<PushChatMember> selectSearchMemberList(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("selectSearchMemberList");

        return this.pushChatMemberService.selectSearchMemberList(pushChatMember);
    }

    /**
     * 비밀 번호를 수정 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember updatePassword(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("updatePassword");

        // 새로운 비밀 번호를 암호화 해서 저장 한다.
        pushChatMember.setPassword(this.pushChatCommon.getEncodedPassword(pushChatMember.getPassword()));

        PushChatMember result = new PushChatMember();

        try {
            this.pushChatMemberService.updatePassword(pushChatMember);
            result.setResult("SUCCESS");
            logger.info("success to update password.");
        } catch (Exception e) {
            result.setResult("FAIL");
            logger.error("fail to update password");
        }

        return result;
    }

    /**
     * 멤버 일반 정보를 수정 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/updateMemberInformation", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember updateMemberInformation(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("updateMemberInformation");

        logger.info("> memberId   : {}", pushChatMember.getMemberId());
        logger.info("> activateYn : {}", pushChatMember.getActivateYn());
        logger.info("> modifyDate : {}", pushChatMember.getModifyDate());

        PushChatMember result = new PushChatMember();

        try {
            this.pushChatMemberService.updateMemberInformation(pushChatMember);
            result.setResult("SUCCESS");
            logger.info("success to update member information.");
        } catch (Exception e) {
            result.setResult("FAIL");
            logger.error("fail to update member information.");
        }

        return result;
    }

    /**
     * 멤버 일반 정보와 프로필 이미지를 같이 수정 한다.
     *
     * @param nickName
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/updateMemberInformationWithProfileImage", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember updateMemberInformationWithProfileImage(
            @RequestParam("memberId") String memberId,
            @RequestParam("nickName") String nickName,
            @RequestParam("phoneNumber") String phoneNumber,
            @RequestParam("email") String email,
            @RequestParam("comment") String comment,
            @RequestParam("profileImageUrl") String profileImageUrl,
            @RequestParam("thumbnailUrl") String thumbnailUrl,
            @RequestParam("gender") String gender,
            @RequestParam("age") String age,
            @RequestParam("countryCode") String countryCode,
            @RequestParam("languageCode") String languageCode,
            @RequestParam("latitude") String latitude,
            @RequestParam("longitude") String longitude,
            @RequestParam("location") String location,
            @RequestParam("openLocationYn") String openLocationYn,
            @RequestParam("personalityType") String personalityType,
            @RequestParam("deviceType") String deviceType,
            @RequestParam("receiveNotificationYn") String receiveNotificationYn,
            @RequestParam("activateYn") String activateYn,
            @RequestParam("modifyDate") String modifyDate,
            @RequestParam("file") MultipartFile file
    ) throws Exception {
        logger.info("updateMemberInformationWithProfileImage");

        PushChatMember parameter = new PushChatMember();

        parameter.setMemberId(memberId);
        parameter.setNickName(nickName);
        parameter.setPhoneNumber(phoneNumber);
        parameter.setEmail(email);
        parameter.setComment(comment);
        parameter.setProfileImageUrl(profileImageUrl);
        parameter.setThumbnailUrl(thumbnailUrl);
        parameter.setGender(gender);
        parameter.setAge(age);
        parameter.setCountryCode(countryCode);
        parameter.setLanguageCode(languageCode);
        parameter.setLatitude(latitude);
        parameter.setLongitude(longitude);
        parameter.setLocation(location);
        parameter.setOpenLocationYn(openLocationYn);
        parameter.setPersonalityType(personalityType);
        parameter.setDeviceType(deviceType);
        parameter.setReceiveNotificationYn(receiveNotificationYn);
        parameter.setActivateYn(activateYn);
        parameter.setModifyDate(modifyDate);

        PushChatMember result = new PushChatMember();

        try {
            if(!file.isEmpty()) {
                // 프로필 이미지 파일 경로를 다시 설정 한다.
                String uploadProfileImagePath = this.httpServletRequest.getSession().getServletContext().getRealPath("/") + uploadProfileImageDirectory;
                logger.info("uploadProfileImagePath      : {}", uploadProfileImagePath);
                parameter.setProfileImageUrl(uploadProfileImageUrl + file.getOriginalFilename());

                // 프로필 썸네일 파일 경로를 다시 설정 한다.
                String uploadProfileThumbnailPath = this.httpServletRequest.getSession().getServletContext().getRealPath("/") + uploadProfileThumbnailDirectory;
                logger.info("uploadProfileThumbnailPath  : {}", uploadProfileThumbnailPath);
                parameter.setThumbnailUrl(uploadProfileThumbnailUrl + file.getOriginalFilename());

                // 멤버 정보를 수정 한다.
                this.pushChatMemberService.updateMemberInformationWithProfileImage(parameter, uploadProfileImagePath, uploadProfileThumbnailPath, file);
                result.setResult("SUCCESS");
                logger.info("success to update member information.");
            } else {
                result.setResult("FAIL");
                logger.error("fail to update member information.");
            }
        } catch (Exception e) {
            result.setResult("FAIL");
            logger.error("fail to update member information.");
        }

        return result;
    }

    /**
     * 닉네임 중복 확인을 한다.
     *
     * @param pushChatMember
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/selectDuplicationNickName", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public PushChatMember selectDuplicationNickName(@RequestBody PushChatMember pushChatMember) throws Exception {
        logger.info("selectDuplicationNickName");

        logger.info("memberId   : {}", pushChatMember.getMemberId());
        logger.info("nickName   : {}", pushChatMember.getNickName());
        logger.info("activateYn : {}", pushChatMember.getActivateYn());

        return this.pushChatMemberService.selectDuplicationNickName(pushChatMember);
    }
}
